/*
Copyright (C) 2012  Christoph Schnack, Berlin (Germany)

This file is part of Tribuit.

    Tribuit is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Tribuit is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Tribuit.  If not, see <http://www.gnu.org/licenses/>.
*/
package WordTable;

/**
 * @author Christoph Schnack
 *
 */

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.*;
import java.awt.print.*;

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;

import GuiTools.TribuitFrame;
import Settings.Language;

public class PrintPreview extends TribuitFrame{
		protected int m_wPage;
        protected int m_hPage;
        protected Printable m_target;
        protected JComboBox m_cbScale;
        protected PreviewContainer m_preview;
        private Language LANG;

        public PrintPreview(Language lang,Printable target){
        	super(lang.getPrintPreview());
        	LANG = lang;
        	setSize(600, 400);
        	m_target = target;
        	JButton closeBtn = new JButton(LANG.getClose());
        	closeBtn.addActionListener(new ActionListener(){
        		public void actionPerformed(ActionEvent e){
        			dispose();
        		}
        	});
                
        	String[] scales = { "10 %", "50 %", "100 %", "150 %" };
        	m_cbScale = new JComboBox(scales);
        	ActionListener lst = new ActionListener(){
        		public void actionPerformed(ActionEvent e){
        			Thread runner = new Thread(){
        				public void run(){
        					String str = m_cbScale.getSelectedItem(). toString();
        					if (str.endsWith("%")) str = str.substring(0, str.length() - 1);
        					str = str.trim();
        					int scale = 0;
        					try{
        						scale = Integer.parseInt(str);
        					}
        					catch (NumberFormatException ex){
        						return;
        					}
        					int w = (int)(m_wPage * scale / 100);
        					int h = (int)(m_hPage * scale / 100);
        					Component[] comps = m_preview.getComponents();
        					for (int k = 0; k < comps.length; k++){
        						if (!(comps[k] instanceof PagePreview)) continue;
        						PagePreview pp = (PagePreview) comps[k];
        						pp.setScaledSize(w, h);
        					}
        					m_preview.doLayout();
        					m_preview.getParent().getParent().validate();
        				}
        			};
        			runner.start();
        		}
        	};
        	m_cbScale.addActionListener(lst);
        	m_cbScale.setMaximumSize(m_cbScale.getPreferredSize());
        	JPanel buttonPanel = new JPanel();
        	buttonPanel.add(closeBtn);
        	buttonPanel.add(m_cbScale);

        	m_preview = new PreviewContainer();

        	PrinterJob prnJob = PrinterJob.getPrinterJob();
        	PageFormat pageFormat = prnJob.defaultPage();
        	if (pageFormat.getHeight() == 0 || pageFormat.getWidth() == 0){
        		System.err.println("Unable to determine default page size");
        		return;
        	}
        	m_wPage = (int)(pageFormat.getWidth());
        	m_hPage = (int)(pageFormat.getHeight());
        	int scale = 10;
        	int w = (int)(m_wPage * scale / 100);
        	int h = (int)(m_hPage * scale / 100);

        	int pageIndex = 0;
        	try{
        		while (true){
        			BufferedImage img = new BufferedImage(m_wPage, m_hPage, BufferedImage.TYPE_INT_RGB);
        			Graphics g = img.getGraphics();
        			g.setColor(Color.white);
        			g.fillRect(0, 0, m_wPage, m_hPage);
        			if (target.print(g, pageFormat, pageIndex) != Printable.PAGE_EXISTS)break;
        			PagePreview pp = new PagePreview(w, h, img);
        			m_preview.add(pp);
        			pageIndex++;
        		}
        	}
        	catch (PrinterException e){
        		e.printStackTrace();
        		System.err.println("Printing error: "+e.toString());
        	}
        	
        	JScrollPane ps = new JScrollPane(m_preview);
        	ps.getVerticalScrollBar().setUnitIncrement(30);
        	
        	getContentPane().add(ps, BorderLayout.CENTER);
        	getContentPane().add(buttonPanel, BorderLayout.SOUTH);
        	setResizable(true);
        	setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        	setVisible(true);
        	m_cbScale.setSelectedIndex(2);
        }

        class PreviewContainer extends JPanel{
        	protected int H_GAP = 16;
        	protected int V_GAP = 10;

        	public Dimension getPreferredSize(){
        		int n = getComponentCount();
        		if (n == 0) return new Dimension(H_GAP, V_GAP);
        		Component comp = getComponent(0);
        		Dimension dc = comp.getPreferredSize();
        		int w = dc.width;
        		int h = dc.height;
        		Dimension dp = getParent().getSize();
        		int nCol = Math.max((dp.width - H_GAP) / (w + H_GAP), 1);
        		int nRow = n / nCol;
        		if (nRow * nCol < n) nRow++;

        		int ww = nCol * (w + H_GAP) + H_GAP;
        		int hh = nRow * (h + V_GAP) + V_GAP;
        		Insets ins = getInsets();
        		return new Dimension(ww + ins.left + ins.right, hh + ins.top + ins.bottom);
        	}

        	public Dimension getMaximumSize(){
        		return getPreferredSize();
        	}

        	public Dimension getMinimumSize(){
        		return getPreferredSize();
        	}

        	public void doLayout(){
        		Insets ins = getInsets();
        		int x = ins.left + H_GAP;
        		int y = ins.top + V_GAP;

        		int n = getComponentCount();
        		if (n == 0) return;
        		Component comp = getComponent(0);
        		Dimension dc = comp.getPreferredSize();
        		int w = dc.width;
        		int h = dc.height;

        		Dimension dp = getParent().getSize();
        		int nCol = Math.max((dp.width - H_GAP) / (w + H_GAP), 1);
        		int nRow = n / nCol;
        		if (nRow * nCol < n) nRow++;

        		int index = 0;
        		for (int k = 0; k < nRow; k++){
        			for (int m = 0; m < nCol; m++){
        				if (index >= n) return;
        				comp = getComponent(index++);
        				comp.setBounds(x, y, w, h);
        				x += w + H_GAP;
        			}
        			y += h + V_GAP;
        			x = ins.left + H_GAP;
        		}
        	}
        }

        class PagePreview extends JPanel{
        	protected int m_w;
        	protected int m_h;
        	protected Image m_source;
        	protected Image m_img;

        	public PagePreview(int w, int h, Image source){
        		m_w = w;
        		m_h = h;
        		m_source = source;
        		m_img = m_source.getScaledInstance(m_w, m_h, Image.SCALE_SMOOTH);
        		m_img.flush();
        		setBackground(Color.white);
        		setBorder(new MatteBorder(1, 1, 2, 2, Color.black));
        	}

        	public void setScaledSize(int w, int h){
        		m_w = w;
        		m_h = h;
        		m_img = m_source.getScaledInstance(m_w, m_h, Image.SCALE_SMOOTH);
        		repaint();
        	}

        	public Dimension getPreferredSize(){
        		Insets ins = getInsets();
        		return new Dimension(m_w + ins.left + ins.right, m_h + ins.top + ins.bottom);
        	}

        	public Dimension getMaximumSize(){
        		return getPreferredSize();
        	}

        	public Dimension getMinimumSize(){
        		return getPreferredSize();
        	}

        	public void paint(Graphics g){
        		g.setColor(getBackground());
        		g.fillRect(0, 0, getWidth(), getHeight());
        		g.drawImage(m_img, 0, 0, this);
        		paintBorder(g);
        	}
        }
}


